﻿using mozhi.smarterp.BasicData.Enums;
using mozhi.smarterp.BasicData.NumberRules.Repositories;
using mozhi.smarterp.BasicData.NumberRules.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;

namespace mozhi.smarterp.BasicData.NumberRules
{
    public class DocumentNumberRuleAppService : BasicDataAppService, IDocumentNumberRuleAppService
    {
        private IDocumentNumberRuleRepository _repository;
        private DocumentNumberRuleManager _manager;

        public DocumentNumberRuleAppService(IDocumentNumberRuleRepository repository , DocumentNumberRuleManager manager)
        {
            _repository = repository;
            _manager = manager;
        }

        public async Task<DocumentNumberRuleDto> CreateAsync(DocumentNumberRuleCreateDto input)
        {
            var numberRule = await _manager.GetAsync(null, input.Name, input.Type, input.Prefix, input.FlowLength);

            var otherDefaultNumberRules = await _manager.SetDefaultRuleAsync(numberRule);

            numberRule = await _repository.InsertAsync(numberRule);

            await _repository.UpdateManyAsync(otherDefaultNumberRules);

            return ObjectMapper.Map<DocumentNumberRule , DocumentNumberRuleDto>(numberRule);
        }

        public async Task DeleteAsync(Guid id)
        {
            var numberRule = await _repository.GetAsync(id);

            if(numberRule == null)
                throw new UserFriendlyException($"单据编码规则:{id}不存在");

            await _repository.DeleteAsync(id);
        }

        public async Task<DocumentNumberGenerateDto> GenerateNumberAsync(DocumentType type, string currentNumber)
        {
            var result = new DocumentNumberGenerateDto() { Type = type, Number = null };

            var numberRule = (await _repository.GetListAsync(type, true)).FirstOrDefault();

            if (numberRule == null)
                return result;

            result.Number = numberRule.Next(currentNumber);

            return result;

        }

        public async Task<DocumentNumberRuleDto> GetAsync(Guid id)
        {
            var numberRule = await _repository.GetAsync(id);

            return ObjectMapper.Map<DocumentNumberRule, DocumentNumberRuleDto>(numberRule);
        }

        public async Task<PagedResultDto<DocumentNumberRuleDto>> GetListAsync(PagedAndSortedResultRequestDto filter)
        {
            var numberRules = await _repository.GetPagedListAsync(filter.SkipCount, filter.MaxResultCount, filter.Sorting ?? nameof(DocumentNumberRuleDto.Type));

            var count = await _repository.GetCountAsync();

            return new PagedResultDto<DocumentNumberRuleDto>()
            {
                Items = ObjectMapper.Map<List<DocumentNumberRule>, List<DocumentNumberRuleDto>>(numberRules),
                TotalCount = count
            };
        }

        public async Task<DocumentNumberRuleDto> UpdateAsync(DocumentNumberRuleUpdateDto input)
        {
            var numberRule = await _manager.GetAsync(input.Id, input.Name, null, input.Prefix, input.FlowLength);

            var otherDefaultNumberRules = await _manager.SetDefaultRuleAsync(numberRule);

            numberRule = await _repository.UpdateAsync(numberRule);

            await _repository.UpdateManyAsync(otherDefaultNumberRules);

            return ObjectMapper.Map<DocumentNumberRule, DocumentNumberRuleDto>(numberRule);
        }
    }
}
